$(document).ready(function() {

    function arrayPush(array, name, value) {
        if (!array.push) {
            alert("Array type expected here.")
        }
        array.push({
            "name": name,
            "value": value
        });
    }
    function getData(target) {
        var json = $(target).data("data");
        if (json) {
            return jQuery.parseJSON(json);
        }
        return undefined;
    }

    var baseUrl = request.context;
    var model = {
        id: request.id,
        columns: jQuery.parseJSON(request.fieldsJson),
        pageSize: request.pageSize
    };
    var parentFields = [ "COUNTERPARTY", "DB_TYPE" ]; // TODO get from java
    var parentFieldValueIndices = [ 0, 0 ]; // TODO get from java
    var classes = {
        "Next": "open-details",
        "COUNTERPARTY": "open-details left",
        "DB_TYPE": "open-details left",
        "Count": "right"
    };
    
    $('.data-table .open-details').live('click', function(){
        $(this).toggleClass('open');
        var tr = this.parentNode;
        var siblings = $(tr).next();
        var details;
        if (siblings.length > 0) {
            if ($(siblings[0]).hasClass('details')) {
                details = siblings[0];
            }
        }
        if ($(this).hasClass('open')) {
            if (details) {
                $(details).show();
            } else {

                var table = tr.parentNode.parentNode;
                var controller = $(table).data('controller');
                var data = controller.table.fnGetData(tr);
                var level = controller.level + 1;

                // copy current params
                var params = controller.params.slice(0);
                // add criteria based on the "parent" field (e.g. COUNTERPARTY)
                var index = controller.level;
                var field = parentFields[index];
                var parentParam = 'parent[' + field + ']'
                var value = data[parentFieldValueIndices[index]]
                arrayPush(params, parentParam, value);

                details = controller.table.fnOpen(tr, '<fieldset class="'
                    + 'counterparty-list-box data-table  counterparty-list-box-' + level
                    + '"><table class="counterparty-list"></table></fieldset>',
                    "details-box");
                details.className = "details " + tr.className;

                var selector = $(details).find('.counterparty-list-box-' + level);
                var detailsController = new TableController(selector, level, params);
                $(tr).data("details", detailsController);

            }
            $(tr).children().css("border-bottom-width", "0");
        } else {
            if (details) {
                $(details).hide();
            }
            $(tr).children().css("border-bottom-width", "1px");
        }
    });

    /*
     *  @param tableSelector table container selector (each table is wrapped with fieldbox),
     *  @param level hierarchy level
     *  @param params additional filter params that should be taken into account on each request.
     */
    function TableController(tableSelector, level, params) {
        var thisController = this;
        this.level = level;
        this.params = params;
        this.table = null;
            
        var doGetServerData = function(source, params, callback) {
            for (var i = 0; i < thisController.params.length; i++) {
                var item = thisController.params[i];
                params.push(item);
            }
            arrayPush(params, "id", request.id);
            arrayPush(params, "level", level);

            var filterParams = $('.data-filter-form').serializeArray();
            params = params.concat(filterParams);

            jQuery.ajax({
                "url": baseUrl + "/extract/data-table.html",
                "type": "POST",
                "data": params,
                "dataType": "json",
                "success": callback,
                "error": function(request, status, error) {
                    alert("Getting data from server error: " + error);
                }
            });
        };

        $(tableSelector).each(function() {
            thisController.staticData = getData(this);
            var tableSelector = $(this).children("table").first();
            tableSelector.data("controller", thisController);

            var columns = new Array();
            var columnNames = model.columns[thisController.level];
            for (var i in columnNames) {
                var name = columnNames[i];
                var cls = "left";
                if (classes[name]) {
                    cls = classes[name];
                }
                if (name == "Next") {
                    name = "";
                }
                columns.push({
                    "aTargets": [ i ],
                    "sClass": cls,
                    "sTitle": name,
                    "bSortable": false
                });
            }

            thisController.table = tableSelector.dataTable({
                "bStateSave": false,
                "bScrollCollapse": true,
                "bFilter": false,
                "bSort": false,
                "bInfo": false,
                "bAutoWidth": false,
                "bLengthChange": false,
                "bServerSide": true,
                "bProcessing": true,
                "iDisplayLength": model.pageSize,
                "fnServerData": doGetServerData,
                "sPaginationType": "full_numbers",
                "aoColumns": columns,
                "fnDrawCallback": function(settings) {
                    var sibs = $(settings.nTable).siblings('.dataTables_paginate');
                    if (settings._iRecordsTotal <= model.pageSize) {
                        if (sibs.length != 1) {
                            alert("Bad components tree: " + sibs);
                        }
                        sibs.hide();
                    } else {
                        sibs.show();
                    }
                },
                
                "eof": true
            });
        });
    }

    var mainController = new TableController('.data-table', 0, []);

    $('.data-table-refresh').click(function() {
        mainController.table.fnDraw();
    });

    $(".input-cob").each(function() {
        var input = this;
        var button = $(this).parent().children(".input-date-button").get(0);
        Calendar.setup( {
            inputField : input, // ID of the input field
            ifFormat : "%Y%m%d", // the date format
            button : button, // ID of the button
            onUpdate: function() {
                showFormUpdateButton($(input).closest('form'));
            },
            eof: null
        });
    });

});
